﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace SecurEntityLib
{
    public sealed class SecretKeyStorage
    {
        private static string SECURENTITY_FRIENDLY_NAME = "SecurEntity";

        private static readonly SecretKeyStorage instance = new SecretKeyStorage();
        private byte[] secretKey;

        private SecretKeyStorage()
        {
            X509Certificate2 cert = null;

            //
            // Open the certificate store
            //

            X509Store myMachineStore = new X509Store(
                StoreName.My, StoreLocation.CurrentUser);
            myMachineStore.Open(
                OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

            //
            // Find the certificate
            //

            foreach (X509Certificate2 c in myMachineStore.Certificates)
            {
                if (0 == string.Compare(
                        c.FriendlyName, SECURENTITY_FRIENDLY_NAME) &&
                    true == c.HasPrivateKey)
                {
                    cert = c;
                    break;
                }
            }

            if (null == cert)
                throw new Exception("No SecurEntity certificate found");

            //
            // Create a hash
            //

            SHA1Managed sha = new SHA1Managed();
            sha.Initialize();
            byte[] data = cert.GetPublicKey();
            sha.TransformBlock(data, 0, data.Length, data, 0);
            data = cert.SubjectName.RawData;
            sha.TransformFinalBlock(data, 0, data.Length);

            //
            // Sign the hash
            //
            
            RSACryptoServiceProvider rsa = 
                (RSACryptoServiceProvider) cert.PrivateKey;
            RSAPKCS1SignatureFormatter pkcs1Signer = 
                new RSAPKCS1SignatureFormatter(rsa);
            pkcs1Signer.SetHashAlgorithm("SHA1");
            secretKey = pkcs1Signer.CreateSignature(sha.Hash);
        }

        public static SecretKeyStorage Instance
        {
            get
            {
                return instance;
            }
        }

        public byte[] SecretKey
        {
            get { return secretKey; }
            set { secretKey = value; }
        }
    }
}
